package com.tanhua.server;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.itheima.commons.utils.Constants;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.dubbo.api.MovementApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VisitorsApi;
import com.tanhua.exception.BusinessException;
import com.tanhua.interceptor.UserHolder;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.MovementsVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.VisitorsVo;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class MovementService {
    @DubboReference
    private MovementApi movementApi;
    @Autowired
    private OssTemplate ossTemplate;
    @DubboReference
    private UserInfoApi userInfoApi;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @DubboReference
    private VisitorsApi visitorsApi;
    @Autowired
    private UserFreezeService userFreezeService;

    /**
     * 发布动态
     *
     * @param movement
     * @param multipartFile
     * @throws IOException
     */
    public void publishMovement(Movement movement, MultipartFile[] multipartFile) throws IOException {
        //判断是否被冻结
        userFreezeService.checkUserStatus("3", UserHolder.getUserId(),"您已被禁止发布动态，详情请联系管理员");

        //判断动态文本是否为空
        if (StringUtils.isEmpty(movement.getTextContent())) {
            throw new BusinessException(ErrorResult.contentError());
        }

        //获取当前用户Id
        Long userId = UserHolder.getUserId();
        //
        ArrayList<String> urlList = new ArrayList<>();
        movement.setUserId(userId);
        for (MultipartFile file : multipartFile) {
            String urlImg = ossTemplate.upload(file.getOriginalFilename(), file.getInputStream());
            urlList.add(urlImg);
        }
        movement.setMedias(urlList);
        movementApi.publish(movement);
    }

    /**
     * 查询动态
     *
     * @param userId
     * @param page
     * @param pagesize
     * @return
     */

    public PageResult findByUserId(Long userId, Integer page, Integer pagesize) {
        if (userId == 0 || userId == null) {
            userId = UserHolder.getUserId();
        }
        //查询用户所有动态信息
        PageResult pageResult = movementApi.findByUserId(userId, page, pagesize);
        List<Movement> items = (List<Movement>) pageResult.getItems();
        if (items == null) {
            pageResult = new PageResult();
            return pageResult;
        }
        //查询用户详细信息
        UserInfo userInfo = userInfoApi.getById(userId);
//        List<MovementsVo> voList = new ArrayList<>();
//        for (Movement item : items) {
//            MovementsVo movementsVo= MovementsVo.init(userInfo, item);
//            voList.add(movementsVo);
//        }
        List<MovementsVo> voList = items.stream().map((item) -> {
            return MovementsVo.init(userInfo, item);
//            MovementsVo movementsVo = MovementsVo.init(userInfo, item);
//            return movementsVo;
        }).collect(Collectors.toList());

        pageResult.setItems(voList);

        return pageResult;
    }

    /**
     * 好友动态
     *
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult findFriendMovements(Integer page, Integer pagesize) {
        Long userId = UserHolder.getUserId();
        List<Movement> movementList = movementApi.findFriendMovements(page, pagesize, userId);

        if (CollUtil.isEmpty(movementList)) {
            return new PageResult();
        }

        List<Long> userIds = CollUtil.getFieldValues(movementList, "serId", Long.class);

        Map<Long, UserInfo> userInfoMap = userInfoApi.getByIds(userIds, null);
        List<MovementsVo> voList = movementList.stream().map((movement -> {
            Long id = movement.getUserId();
            if (userInfoMap.get(id) != null) {
                return MovementsVo.init(userInfoMap.get(id), movement);
            }
            return null;
        })).filter(Objects::nonNull).collect(Collectors.toList());

//        PageResult pageResult = new PageResult();
//        pageResult.setPage(page);
//        pageResult.setPagesize(pagesize);
//        pageResult.setItems(voList);
        return getPageResult(page, pagesize, movementList);
    }

    /**
     * 推荐动态
     *
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult findRecommendMovements(Integer page, Integer pagesize) {

        Long userId = UserHolder.getUserId();

        String redisKey = Constants.MOVEMENTS_RECOMMEND + userId;
        String redisValue = redisTemplate.opsForValue().get(redisKey);

        List<Movement> list = Collections.EMPTY_LIST;
        if (StringUtils.isEmpty(redisValue)) {
            //随机动态
            list = movementApi.randomMovements(pagesize);
        } else {
            String[] strings = redisValue.split(",");
            //判断当前页是否能够加载，起始页是否小于总页数
            if ((page - 1) * pagesize < strings.length) {
                //将Pid；类型转换为Long类型并存储到List集合中
                List<Long> pids = Arrays.stream(strings)
                        .skip((page - 1) * pagesize)
                        .limit(pagesize)
                        .map((Long::parseLong))
                        .collect(Collectors.toList());
                //根据Pid加载动态
                list = movementApi.findMovementsByPids(pids);
            }
        }
        return getPageResult(page, pagesize, list);
    }


    private PageResult getPageResult(Integer page, Integer pagesize, List<Movement> list) {

        if (CollUtil.isEmpty(list)) {
            return new PageResult();
        }

        //4、提取动态发布人的id列表
        List<Long> userIds = CollUtil.getFieldValues(list, "userId", Long.class);

        //5、根据用户的id列表获取用户详情
        Map<Long, UserInfo> map = userInfoApi.getByIds(userIds, null);

        //6、一个Movement构造一个vo对象
        List<MovementsVo> vos = new ArrayList<>();
        for (Movement movement : list) {
            UserInfo userInfo = map.get(movement.getUserId());
            if (userInfo != null) {
                MovementsVo vo = MovementsVo.init(userInfo, movement);
                //查询redis初始化hasLiked、hasLoved
                initLikeOrLove(movement, vo);
                vos.add(vo);
            }
        }

        //7、构造PageResult并返回
        return new PageResult(page, pagesize, 0L, vos);

    }

    /**
     * 根据动态Id查询动态心情，包括评论、点赞和喜欢
     *
     * @param movementId
     * @return
     */
    public MovementsVo findByMovementId(String movementId) {
        //1、调用api根据id查询动态详情
        Movement movement = movementApi.findByMovementId(movementId);

        //2、转化vo对象
        if (movement != null) {
            UserInfo userInfo = userInfoApi.getById(movement.getUserId());

            MovementsVo movementsVo = MovementsVo.init(userInfo, movement);
            initLikeOrLove(movement, movementsVo);

            return movementsVo;
        } else {
            return null;
        }
    }

    //初始化hasLiked、hasLoved
    private void initLikeOrLove(Movement movement, MovementsVo movementsVo) {
        String key = Constants.MOVEMENTS_INTERACT_KEY + movement.getId().toString();
        String hashKey = Constants.MOVEMENT_LIKE_HASHKEY + UserHolder.getUserId();
        String hashKey2 = Constants.MOVEMENT_LOVE_HASHKEY + UserHolder.getUserId();
        if (redisTemplate.opsForHash().hasKey(key, hashKey)) {
            movementsVo.setHasLiked(1);
        }
        if (redisTemplate.opsForHash().hasKey(key, hashKey2)) {
            movementsVo.setHasLoved(1);
        }
    }

    public List<VisitorsVo> queryVisitorsList() {
//      //查询访问时间
        String key = Constants.VISITORS;
        String hashKey = String.valueOf(UserHolder.getUserId());
        String value = (String) redisTemplate.opsForHash().get(key, hashKey);
        Long date = Objects.isNull(value) ? null : Long.valueOf(value);

//        //查询访客列表
//        List<Visitors> visitors = visitorsApi.findById(date, UserHolder.getUserId());
//        if (CollUtil.isEmpty(visitors)) {
//            return new ArrayList<>();
//        }
//        //提取访问用户Id
//        List<Long> visitorUserId = CollUtil.getFieldValues(visitors, "visitorUserId", Long.class);
//        //查询用户详情
//        Map<Long, UserInfo> userInfoMap = userInfoApi.getByIds(visitorUserId, null);
//
//        return visitors.stream().map((v -> {
//            UserInfo userInfo = userInfoMap.get(v.getVisitorUserId());
//            if (userInfo != null) {
//                return VisitorsVo.init(userInfo, v);
//            }
//            return null;
//        })).filter(Objects::nonNull).collect(Collectors.toList());
//
//    }


        List<Visitors> visitorsList = visitorsApi.queryMyVisitor(UserHolder.getUserId(), date);

        if (CollUtil.isEmpty(visitorsList)) {
            return Collections.emptyList();
        }

        List<Long> userIds = CollUtil.getFieldValues(visitorsList, "visitorUserId", Long.class);
        Map<Long, UserInfo> userInfoMap = userInfoApi.getByIds(userIds, null);
        Collection<UserInfo> userInfos = userInfoMap.values();


        List<VisitorsVo> visitorsVoList = new ArrayList<>();

        for (Visitors visitor : visitorsList) {
            for (UserInfo userInfo : userInfos) {
                if (ObjectUtil.equals(visitor.getVisitorUserId(), userInfo.getId())) {
                    VisitorsVo visitorsVo = BeanUtil.toBeanIgnoreError(userInfo, VisitorsVo.class);
                    visitorsVo.setGender(userInfo.getGender().toLowerCase());
                    visitorsVo.setFateValue(visitor.getScore().longValue());
                    visitorsVoList.add(visitorsVo);
                    break;
                }
            }
        }

        return visitorsVoList;
    }
}
